package com.summo.demo.service.impl;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collector;
import java.util.stream.Collectors;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson2.JSONObject;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.summo.demo.config.redis.RedisUtil;
import com.summo.demo.dao.AuthMapper;
import com.summo.demo.dao.RoleAuthMapper;
import com.summo.demo.dao.UserMapper;
import com.summo.demo.dao.UserRoleMapper;
import com.summo.demo.entity.AuthDO;
import com.summo.demo.entity.RoleAuthDO;
import com.summo.demo.entity.UserDO;
import com.summo.demo.entity.UserRoleDO;
import com.summo.demo.model.AddReq;
import com.summo.demo.model.UpdateReq;
import com.summo.demo.repository.AuthRepository;
import com.summo.demo.repository.RoleAuthRepository;
import com.summo.demo.repository.UserRepository;
import com.summo.demo.repository.UserRoleRepository;
import com.summo.demo.service.UserService;
import com.summo.demo.service.convert.UserConvert;
import com.summo.demo.service.convert.UserRoleConert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

@Service
public class UserServiceImpl implements UserService {

    @Value("${token.timeout}")
    private Long tokenTimeout;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private UserRoleRepository userRoleRepository;

    @Autowired
    private RoleAuthRepository roleAuthRepository;

    @Autowired
    private AuthRepository authRepository;

    @Autowired
    private RedisUtil redisUtil;

    @Override
    public ResponseEntity<String> login(String userName, HttpServletRequest httpServletRequest,
                                        HttpServletResponse httpServletResponse) {
        //根据名称查询用户信息
        UserDO userDO = userRepository.getOne(new QueryWrapper<UserDO>().lambda().eq(UserDO::getUserName, userName));
        if (Objects.isNull(userDO)) {
            return ResponseEntity.ok("未查询到用户");
        }
        //查询当前用户的角色信息
        List<UserRoleDO> userRoleDOList = userRoleRepository.list(
                new QueryWrapper<UserRoleDO>().lambda().eq(UserRoleDO::getUserId, userDO.getUserId()));
        if (CollectionUtils.isEmpty(userRoleDOList)) {
            return ResponseEntity.ok("当前用户没有角色");
        }
        //查询当前用户的权限
        List<RoleAuthDO> roleAuthDOS = roleAuthRepository.list(new QueryWrapper<RoleAuthDO>().lambda()
                .in(RoleAuthDO::getRoleId, userRoleDOList.stream().map(UserRoleDO::getRoleId).collect(
                        Collectors.toList())));
        if (CollectionUtils.isEmpty(roleAuthDOS)) {
            return ResponseEntity.ok("当前角色没有对应权限");
        }
        //查询权限code
        List<AuthDO> authDOS = authRepository.list(new QueryWrapper<AuthDO>().lambda()
                .in(AuthDO::getAuthId, roleAuthDOS.stream().map(RoleAuthDO::getAuthId).collect(
                        Collectors.toList())));

        //生成唯一token
        String token = UUID.randomUUID().toString();
        //缓存用户信息
        redisUtil.set(token, JSONObject.toJSONString(userDO), tokenTimeout);
        //缓存用户权限信息
        redisUtil.set("auth_" + userDO.getUserId(),
                JSONObject.toJSONString(authDOS.stream().map(AuthDO::getAuthCode).collect(Collectors.toList())),
                tokenTimeout);
        //向localhost中添加Cookie
        Cookie cookie = new Cookie("token", token);
        cookie.setDomain("localhost");
        cookie.setPath("/");
        cookie.setMaxAge(tokenTimeout.intValue());
        httpServletResponse.addCookie(cookie);
        //返回登录成功
        return ResponseEntity.ok(JSONObject.toJSONString(userDO));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<String> add(AddReq addReq) {
        //构建用户对象
        UserDO userDO = UserConvert.toDOWhenSave(addReq);
        //添加数据库
        Boolean insertTag = userRepository.save(userDO);
        if (!insertTag) {
            return ResponseEntity.ok("添加用户失败");
        }
        //添加成功且角色不为空添加用户角色关联关系
        if (!CollectionUtils.isEmpty(addReq.getRoleIdList())) {
            //构建用户角色关联关系
            List<UserRoleDO> userRoleDOS = addReq.getRoleIdList().stream().map(roleId -> UserRoleConert.toDOWhenSave(userDO.getUserId(), roleId)).
                    collect(Collectors.toList());
            //添加到数据库
            userRoleRepository.saveBatch(userRoleDOS);
        }
        //添加用户状态
        return ResponseEntity.ok("添加用户成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<String> delete(Long userId) {
        //删除用户与角色关联关系
        userRoleRepository.remove(new QueryWrapper<UserRoleDO>().lambda().eq(UserRoleDO::getUserId,userId));
        //删除用户信息
        userRepository.remove(new QueryWrapper<UserDO>().lambda().eq(UserDO::getUserId,userId));
        return ResponseEntity.ok("删除用户成功");
    }

    @Override
    public ResponseEntity<String> query(String userName) {
        return null;
    }

    @Override
    public ResponseEntity<String> update(UpdateReq updateReq) {
        return null;
    }
}
